﻿using System;
using System.Collections.Generic;
using System.Text;
using KBEngine.Setting;

namespace KBEngineTool
{
    internal static class EntityDefHelper
    {
        internal static EntitySetting ToSetting(this EntityDef entityDef, EntityLoader entityDefMgr, EntitySetting setting = null)
        {
            setting = setting ?? new EntitySetting();
            setting.name = entityDef.Name;
            setting.register = entityDef.IsRegistered;
            setting.hasClient = entityDef.HasClient;
            setting.entityType = entityDef.EntityType;
            setting.entity = setting.entity ?? new Entity();
            setting.entity.parent = entityDef.Parent != null ? entityDef.Parent.Name : string.Empty;
            if (entityDef.Volatile != null)
            {
                setting.entity.volatilee.position = entityDef.Volatile.Position.GetValueOrDefault();
                setting.entity.volatilee.yaw = entityDef.Volatile.Yaw.GetValueOrDefault();
                setting.entity.volatilee.pitch = entityDef.Volatile.Pitch.GetValueOrDefault();
                setting.entity.volatilee.roll = entityDef.Volatile.Roll.GetValueOrDefault();
                setting.entity.volatilee.optimized = entityDef.Volatile.optimized;
            }
            setting.entity.interfaces = entityDef.Interfaces.ConvertAll(item => item.Name);
            setting.entity.components = entityDef.Components.ConvertAll(item => new Entity.Component()
            {
                componentName = item.Name,
                componentType = item.Component.Name,
                persistent = item.Persistent.GetValueOrDefault(),
            });
            setting.entity.properties = entityDef.Properties.ConvertAll(item => new Entity.Property()
            {
                propertyName = item.Name,
                type = entityDefMgr.GetTypeStr(item.Type),
                defaultVal = item.Default,
                uType = item.Utype.GetValueOrDefault(),
                flags = item.Flags.ToString(),
                persistent = item.Persistent.GetValueOrDefault(),
                databaseLength = item.DatabaseLength.GetValueOrDefault(),
                index = item.IndexType.HasValue ? item.IndexType.ToString() : string.Empty,
            });
            setting.entity.clientMethods = entityDef.ClientMethods.ConvertAll(item => new Entity.Method()
            {
                methodName = item.Name,
                exposed = item.Exposed,
                uType = item.Utype.GetValueOrDefault(),
                args = item.Args.ConvertAll(entityDefMgr.GetTypeStr),
            });
            setting.entity.baseMethods = entityDef.BaseMethods.ConvertAll(item => new Entity.Method()
            {
                methodName = item.Name,
                exposed = item.Exposed,
                uType = item.Utype.GetValueOrDefault(),
                args = item.Args.ConvertAll(entityDefMgr.GetTypeStr),
            });
            setting.entity.cellMethods = entityDef.CellMethods.ConvertAll(item => new Entity.Method()
            {
                methodName = item.Name,
                exposed = item.Exposed,
                uType = item.Utype.GetValueOrDefault(),
                args = item.Args.ConvertAll(entityDefMgr.GetTypeStr),
            });
            return setting;
        }
        internal static void FromSetting(this EntityDef entityDef, EntityLoader entityDefMgr, EntitySetting setting)
        {
            entityDef.Name = setting.name;
            entityDef.EntityType = setting.entityType;
            entityDef.HasClient = setting.hasClient;
            entityDef.IsRegistered = setting.register;
            entityDef.Parent = string.IsNullOrEmpty(setting.entity.parent) ? null : EntityDef.AllEntityDefs[setting.entity.parent];
            {
                entityDef.Volatile.optimized = setting.entity.volatilee.optimized;
                if (setting.entity.volatilee.position != 0)
                    entityDef.Volatile.Position = setting.entity.volatilee.position;
                if (setting.entity.volatilee.yaw != 0)
                    entityDef.Volatile.Yaw = setting.entity.volatilee.yaw;
                if (setting.entity.volatilee.pitch != 0)
                    entityDef.Volatile.Pitch = setting.entity.volatilee.pitch;
                if (setting.entity.volatilee.roll != 0)
                    entityDef.Volatile.Roll = setting.entity.volatilee.roll;
            }
            entityDef.Interfaces = setting.entity.interfaces.ConvertAll(item => EntityDef.AllEntityDefs[item]);
            entityDef.Components = setting.entity.components.ConvertAll(item => 
            {
                var com = new ComponentDef()
                {
                    Name = item.componentName,
                };
                if (!string.IsNullOrEmpty(item.componentType))
                    com.Component = EntityDef.AllEntityDefs[item.componentType];
                if (item.persistent != false)
                    com.Persistent = item.persistent;
                return com;
            });
            entityDef.Properties = setting.entity.properties.ConvertAll(item =>
            {
                var proper = new PropertyDef()
                {
                    Name = item.propertyName,
                    Type = entityDefMgr.GetType(item.type),
                    Default = item.defaultVal,
                    Flags = string.IsNullOrEmpty(item.flags) ? Flags.CELL_PRIVATE : (Flags)Enum.Parse(typeof(Flags), item.flags),
                };
                if (item.uType != 0)
                    proper.Utype = (ushort)item.uType;
                if (item.persistent != false)
                    proper.Persistent = item.persistent;
                if (item.databaseLength != 0)
                    proper.DatabaseLength = item.databaseLength;
                if (!string.IsNullOrEmpty(item.index))
                    proper.IndexType = (IndexType)Enum.Parse(typeof(IndexType), item.index);
                return proper;
            });
            entityDef.ClientMethods = setting.entity.clientMethods.ConvertAll(item => {
                var mehtod = new MethodDef()
                {
                    Name = item.methodName,
                    Exposed = item.exposed,
                    Args = item.args.ConvertAll(entityDefMgr.GetType),
                };
                if (item.uType != 0)
                    mehtod.Utype = item.uType;
                return mehtod;
            });
            entityDef.BaseMethods = setting.entity.baseMethods.ConvertAll(item =>
            {
                var mehtod = new MethodDef()
                {
                    Name = item.methodName,
                    Exposed = item.exposed,
                    Args = item.args.ConvertAll(entityDefMgr.GetType),
                };
                if (item.uType != 0)
                    mehtod.Utype = item.uType;
                return mehtod;
            });
            entityDef.CellMethods = setting.entity.cellMethods.ConvertAll(item =>
            {
                var mehtod = new MethodDef()
                {
                    Name = item.methodName,
                    Exposed = item.exposed,
                    Args = item.args.ConvertAll(entityDefMgr.GetType),
                };
                if (item.uType != 0)
                    mehtod.Utype = item.uType;
                return mehtod;
            });
        }
    }
}
